using SmartLink.Domain.Entity;
using SmartLink.Domain.ExpandEntity;
using SmartLink.Domain.ExpandEntity.Base;
using SmartLink.Domain.IServices;
using SmartLink.DTOS;
using SmartLink.Infrastructure;
using SmartLink.Infrastructure.Cache;
using SmartLink.IRepository;
using SmartLink.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SmartLink.Domain.Services
{
    public class RoleServices : IRoleServices
    {
        private IPER_RoleGroupRepo _IPER_RoleGroupRepo;
        private IPER_UserToRoleRepo _IPER_UserToRoleRepo;
        private IBIZ_OrganizationRepo _IBIZ_OrganizationRepo;

        public RoleServices(IPER_RoleGroupRepo iPER_RoleGroupRepo,
            IPER_UserToRoleRepo iPER_UserToRoleRepo,
            IBIZ_OrganizationRepo iBIZ_OrganizationRepo)
        {
            _IPER_RoleGroupRepo = iPER_RoleGroupRepo;
            _IPER_UserToRoleRepo = iPER_UserToRoleRepo;
            _IBIZ_OrganizationRepo = iBIZ_OrganizationRepo;
        }

        private string RoleNoGenerate(int oid)
        {
            var maxCount = _IPER_RoleGroupRepo.GetRolesCount(oid);
            return string.Format("{0}{1}", oid, (maxCount + 1).ToString().PadLeft(5, '0'));
        }

        public OperationResult AddRole(PER_RoleGroup role)
        {
            bool exist = _IPER_RoleGroupRepo.Exist(role.RoleName, role.OID);
            if (exist)
                return new OperationResult(OperationResultType.ParamError, "角色名称已存在。");
            if (role.RoleName.Equals(ConstData.SuperManagerRoleName) || role.RoleName.Equals(ConstData.OrgManagerRoleName))
                return new OperationResult(OperationResultType.Warning, "非法的角色名称，与内置角色冲突。");
            else
            {
                role.GenerateNo(() => RoleNoGenerate(role.OID));
                _IPER_RoleGroupRepo.Add(role);
                return new OperationResult(OperationResultType.Success);
            }
        }

        public OperationResult UpdateRole(PER_RoleGroup role)
        {
            var originalRole = _IPER_RoleGroupRepo.GetById(role.ID);
            if (originalRole.IsBuildin)
                return new OperationResult(OperationResultType.IllegalOperation, "该角色为内置角色，不可修改。");
            else
            {
                bool repeat = _IPER_RoleGroupRepo.Repeat(role.ID, role.RoleName, role.OID);
                if (repeat)
                    return new OperationResult(OperationResultType.ParamError, "角色名称已存在。");
                if (role.RoleName.Equals(ConstData.SuperManagerRoleName) || role.RoleName.Equals(ConstData.OrgManagerRoleName))
                    return new OperationResult(OperationResultType.Warning, "非法的角色名称，与内置角色冲突。");
                else
                {
                    bool disabling = role.Enabled == 0 && originalRole.Enabled == 1;

                    originalRole.RoleName = role.RoleName;
                    originalRole.RoleDesc = role.RoleDesc;
                    originalRole.Enabled = role.Enabled;
                    _IPER_RoleGroupRepo.Update(originalRole);

                    if (disabling)
                    {
                        var roleUserIds = RoleToUsersCache.GetUsers(role.ID);
                        if (roleUserIds != null && roleUserIds.Count > 0)
                        {
                            foreach (var userId in roleUserIds)
                            {
                                UserInfoCaches.SetExpires(userId);
                            }
                        }
                    }

                    return new OperationResult(OperationResultType.Success);
                }
            }
        }

        public OperationResult DeleteRole(int id)
        {
            IList<PER_UserToRole> userToRoles = _IPER_UserToRoleRepo.GetRoleUsers(id);
            if (userToRoles.Count > 0)
                return new OperationResult(OperationResultType.IllegalOperation, "该角色已有关联用户，不能删除。");
            else
            {
                PER_RoleGroup role = _IPER_RoleGroupRepo.GetById(id);
                if (role.IsBuildin)
                    return new OperationResult(OperationResultType.IllegalOperation, "该角色为预置角色，不可删除。");
                else
                {
                    _IPER_RoleGroupRepo.DeleteLogic(id);
                    return new OperationResult(OperationResultType.Success);
                }
            }
        }

        public PER_RoleGroup GetRole(int roleId)
        {
            return _IPER_RoleGroupRepo.GetById(roleId);
        }

        public IEnumerable<PER_RoleGroupExpand> GetRolePaged(bool? enabled, string keyWord, Pagination pagination)
        {
            return _IPER_RoleGroupRepo.GetRolePaged(enabled, keyWord, CurrentUser.Current.ROID, pagination);
        }

        public IList<PER_RoleGroup> GetRoleListByOID(int oid)
        {
            var roid = _IBIZ_OrganizationRepo.GetRootOrganizationId(oid);
            return _IPER_RoleGroupRepo.GetRoleListByOID(roid);
        }

        public void AllotRolesToUser(int userId, IList<int> roleIds)
        {
            _IPER_UserToRoleRepo.AllotRolesToUser(userId, roleIds);
        }

        public static void InitUserRoleRelations()
        {
            IList<PER_UserToRole> userToRoles = PER_UserToRoleRepo.GetAllUserToRoles();
            foreach (PER_UserToRole userToRole in userToRoles)
            {
                UserInfoCaches.AddUserRoleRelation(userToRole.UserID, userToRole.RID, RoleUser.User);
                UserInfoCaches.AddUserRoleRelation(userToRole.UserID, userToRole.RID, RoleUser.Role);
            }
        }
    }
}
